package com.hzit.cart.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.hzit.cart.domain.ItemDTO;
import com.hzit.cart.interceptor.LoginInterceptor;
import com.hzit.cart.service.ICartService;
import com.ruoyi.common.core.constant.HzitConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.system.api.RemoteManagerService;
import com.ruoyi.system.api.domain.Item;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 类名：
 * 作者：WF
 * 功能：
 */
@Service
public class CartServiceImpl implements ICartService {

	@Autowired
	private StringRedisTemplate redisTemplate;
	@Autowired
	private RemoteManagerService managerService;

	public String getLogin(){
		return LoginInterceptor.loginThreadLocal.get();
	}
	//1. 添加商品到购物车中
	@Override
	public void addCart(Integer num, Long id) {
		//1.1 从远程根据sku的id查询出sku商品对象
		R<Item> itemR = managerService.findItemById(id);
		Item item = itemR.getData();
		//1.2 得到登录名

		//1.3 根据是否在redis中存在指定key，判断是否有此商品
		Boolean hasKey = redisTemplate.opsForHash().hasKey(HzitConstants.CART_PREFIX + getLogin(), id + "");
		//1.3.1 如果有此商品就修改redis中此商品的购买数量
		ItemDTO itemDTO = null;
		if(hasKey){
			//1.3.2 根据大key与小key找到此商品
			String v = (String) redisTemplate.opsForHash().get(HzitConstants.CART_PREFIX + getLogin(), id + "");
			//1.3.3 得到从redis中查询出的哪件商品
			itemDTO = JSON.parseObject(v, ItemDTO.class);
			//1.3.4 修改商品的购买数量
			itemDTO.setBuyNum(itemDTO.getBuyNum() + num);
		}else{  // 如果没有此商品就从远程查询出此商品并添加到redis中
			//1.3.5 将item转换为ItemDTO，并设置购买数量
			itemDTO = new ItemDTO();
			BeanUtil.copyProperties(item,itemDTO,true);
			itemDTO.setBuyNum(num);
		}
		//1.4 将上面的商品添加到redis中
		HashOperations<String, Object, Object> hashOperations = redisTemplate.opsForHash();

		hashOperations.put(HzitConstants.CART_PREFIX + getLogin(), id + "",JSON.toJSONString(itemDTO));      // 放数据
		hashOperations.getOperations().expire(HzitConstants.CART_PREFIX + getLogin(),30,TimeUnit.DAYS);      // 设置到期时间
	}

	// 根据sku商品id从redis中查询出sku商品
	@Override
	public ItemDTO getItemFromRedis(Long id) {
		String o = (String) redisTemplate.opsForHash().get(HzitConstants.CART_PREFIX + getLogin(), id + "");
		return JSON.parseObject(o,ItemDTO.class);

	}

	// 【方法一】：从购物车中得到数据并转换为Map<String, List<ItemDTO>>集合
	@Override
	public Map<String, List<ItemDTO>> getCartInfoFromRedis() {
		//{"华为":[{},{}],"百度"：[{}]}
		//1. 得到购物车数据
		List<Object> values = redisTemplate.opsForHash().values(HzitConstants.CART_PREFIX + getLogin());
		//2. 转换为List<ItemDTO>集合
		List<ItemDTO> collect = values.stream().map(m -> {
			ItemDTO dto = JSON.parseObject(m + "", ItemDTO.class);
			return dto;
		}).collect(Collectors.toList());
		//3. 对上面的List<ItemDTO>进行分组（按照商家名字分组）
		Map<String, List<ItemDTO>> map = collect.stream().collect(Collectors.groupingBy(ItemDTO::getSeller));
		return map;
	}
	// 【方法二】：从购物车中得到数据并转换为Map<String, List<ItemDTO>>集合
	public Map<String, List<ItemDTO>> getCartInfoFromRedis2(){
		//1. 得到购物车数据
		List<Object> values = redisTemplate.opsForHash().values(HzitConstants.CART_PREFIX + getLogin());
		//2. 转换为List<ItemDTO>集合
		List<ItemDTO> collect = values.stream().map(m -> {
			ItemDTO dto = JSON.parseObject(m + "", ItemDTO.class);
			return dto;
		}).collect(Collectors.toList());
		//3. 存放商家名字到set集合
		Set<String> sellers = new HashSet<>();
		collect.forEach(c -> {
			sellers.add(c.getSeller());
		});
		//4. 根据set的个数确定map
		Map<String,List<ItemDTO>> map = new HashMap<>();
		for (String seller : sellers) {
			map.put(seller,new ArrayList<>());
		}
		//5. 向map中继续放值进去
		for (ItemDTO dto : collect) {
			if(map.containsKey(dto.getSeller())){
				//5.1 如果map中有指定的key（商家名字）就得到此商家的商品集合，并把此商品dto放到此集合中
				List<ItemDTO> itemDTOS = map.get(dto.getSeller());
				itemDTOS.add(dto);
			}
		}
		return map;
	}



}
